package com.cq.smartelebicycle.service;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import android.app.Service;
import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.util.Log;

import com.cq.smartelebicycle.model.Music;

public class MediaPlaybackService extends Service {

	public static final String META_CHANGED = "com.cq.smartelebicycle.music.metachanged";

	public static final long NONE_MUSIC_ID = -1;

	public static final String POSITION = "item_position";

	private long currentMusicId = NONE_MUSIC_ID;
	private Music mMusic;
	private Cursor mCursor;
	private MediaPlayer mPlayer;
	private Map<Long, Long> mPosMap = new HashMap<Long, Long>();
	private long mPos;

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return mBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.d("luoheng", "service onCreate");
		mPlayer = new MediaPlayer();
		mPlayer.setOnCompletionListener(new OnCompletionListener() {
			
			@Override
			public void onCompletion(MediaPlayer mp) {
				// TODO Auto-generated method stub
				if (currentMusicId != NONE_MUSIC_ID) {
					next();
				}
			}
		});
		mMusic = new Music();
	}

	private Cursor getCursorForId(long lid) {
		String id = String.valueOf(lid);

		Cursor c = getContentResolver().query(
				MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, Music.MUSIC_COLS,
				"_id=" + id, null, null);
		return c;
	}

	public long getCurrentMusicId() {
		return currentMusicId;
	}

	private void notifyChange(String what) {
		Intent i = new Intent(what);
		i.putExtra(POSITION, mPos);
		sendBroadcast(i);
	}

	private final IBinder mBinder = new ServiceStub(this);

	static class ServiceStub extends IMediaPlaybackService.Stub {
		WeakReference<MediaPlaybackService> mService;

		ServiceStub(MediaPlaybackService service) {
			mService = new WeakReference<MediaPlaybackService>(service);
		}

		@Override
		public void setCurrentMusicId(long musicId) throws RemoteException {
			// TODO Auto-generated method stub
			mService.get().setCurrentMusicId(musicId);
		}

		@Override
		public void play() throws RemoteException {
			// TODO Auto-generated method stub
			mService.get().play();
		}

		@Override
		public void pause() throws RemoteException {
			// TODO Auto-generated method stub
			mService.get().pause();
		}

		@Override
		public void next() throws RemoteException {
			// TODO Auto-generated method stub
			mService.get().next();
		}

		@Override
		public void last() throws RemoteException {
			// TODO Auto-generated method stub
			mService.get().last();
		}

		@Override
		public int getCurrentPosition() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().getCurrentPosition();
		}

		@Override
		public int getDuration() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().getDuration();
		}

		@Override
		public void seekTo(int msec) throws RemoteException {
			// TODO Auto-generated method stub
			mService.get().seekTo(msec);
		}

		@Override
		public boolean isPlaying() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().isPlaying();
		}

		@Override
		public String getMusicTitle() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().getMusicTitle();
		}

		@Override
		public long getCurrentMusicId() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().getCurrentMusicId();
		}

		@Override
		public boolean makeAutoShuffleList() throws RemoteException {
			// TODO Auto-generated method stub
			return mService.get().makeAutoShuffleList();
		}

	}

	public void setCurrentMusicId(long musicId) {
		// TODO Auto-generated method stub
		synchronized (this) {
			currentMusicId = musicId;
		}
	}

	public String getMusicTitle() {
		// TODO Auto-generated method stub
		return mMusic.getTitle();
	}

	public void last() {
		// TODO Auto-generated method stub
		mPos--;
		if (mPos <= mPosMap.size()) {
			mPos = mPosMap.size() - 1;
		} 
		currentMusicId = mPosMap.get(mPos);
		play();
	}

	public void next() {
		// TODO Auto-generated method stub
		mPos++;
		if (mPos >= mPosMap.size()) {
			mPos = 0;
		} 
		currentMusicId = mPosMap.get(mPos);
		play();
	}

	public void pause() {
		// TODO Auto-generated method stub
		if (mPlayer.isPlaying()) {
			mPlayer.pause();
		} else {
			mPlayer.start();
		}
	}

	public void play() {
		// TODO Auto-generated method stub
		if (currentMusicId != NONE_MUSIC_ID) {
			mCursor = getCursorForId(currentMusicId);
			if (mCursor != null && mCursor.moveToNext()) {
				mMusic = mMusic.initMusicFromCursor(mCursor);
				try {
					mPlayer.reset();
					Log.d("luoheng", "play path=" + mMusic.getData());
					mPlayer.setDataSource(mMusic.getData());
					mPlayer.prepare();
					mPos = getCurrentIndex(currentMusicId);
					mPlayer.start();
					notifyChange(META_CHANGED);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					Log.d("luoheng", "play, e = " + e);
				}
			}
		}

	}

	private long getCurrentIndex(long currentId) {
		// TODO Auto-generated method stub
		Iterator it = mPosMap.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<Long, Long> entry = (Entry<Long, Long>) it.next();
			if (entry.getValue() == Long.valueOf(currentId)) {
				return entry.getKey();
			}
		}
		return -1;
	}

	public int getCurrentPosition() {
		return mPlayer.getCurrentPosition();
	}

	public int getDuration() {
		return mPlayer.getDuration();
	}

	public void seekTo(int msec) {
		mPlayer.seekTo(msec);
	}

	public boolean isPlaying() {
		return mPlayer.isPlaying();
	}

	public boolean makeAutoShuffleList() {
		mPosMap.clear();
		ContentResolver res = getContentResolver();
		Cursor c = null;
		try {
			c = res.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
					new String[] { MediaStore.Audio.Media._ID },
					MediaStore.Audio.Media.IS_MUSIC + "=1", null, null);
			if (c == null || c.getCount() == 0) {
				return false;
			}
			int len = c.getCount();
			long[] list = new long[len];
			for (int i = 0; i < len; i++) {
				c.moveToNext();
				mPosMap.put(Long.valueOf(i), c.getLong(0));
			}
			return true;
		} catch (RuntimeException ex) {
		} finally {
			if (c != null) {
				c.close();
			}
		}
		return false;
	}

}
